#!/usr/bin/env python
# _*_ coding:utf-8 _*_
# 声明yaml用例格式

from dataclasses import dataclass, asdict

import allure

from commons.templates import Template
import yaml
import logging
logger = logging.getLogger(__name__)


@dataclass
class CaseInfo:
    """用例信息"""

    title: str
    request: dict
    extract: dict
    validate: dict
    parametrize: list = ""
    epic: str = "项目名称：默认项目"
    feature: str = "默认feature"
    story: str = "默认story"

    def to_yaml(self) -> str:
        """序列化成yaml字符串"""

        yaml_str = yaml.dump(asdict(self))

        return yaml_str

    @classmethod
    def by_yaml(cls, yaml_str):
        """反序列化成python"""
        obj = cls(**yaml.safe_load(yaml_str))

        return obj

    @allure.step("断言")
    def assert_all(self):
        if not self.validate:
            return

        for assert_type, assert_data in self.validate.items():
            for msg, data in assert_data.items():
                a, b = str(data[0]), str(data[1])
                #         print(assert_type, a, b, msg)
                # 1/0
                match assert_type:
                    case "equals":
                        logger.info(f"assert {a} == {b}, {msg}")
                        assert a == b, msg
                    case "not_equals":
                        logger.info(f"assert {a} != {b}, {msg}")
                        assert a != b, msg
                    case "contains":
                        logger.info(f"assert {a} in {b}, {msg}")
                        assert a in b, msg
                    case "not_contains":
                        logger.info(f"assert {a} not in {b}, {msg}")
                        assert a not in b, msg

    def ddt(self) -> list:  # 返回一个列表，列表中应该包含N个注入了变量的CaseInfo

        case_list = []

        if not self.parametrize:  # 没有使用数据驱动测试
            case_list.append(self)
        else:  # 使用数据驱动测试
            args_name = self.parametrize[0]
            args_value_list = self.parametrize[1:]

            for args_value in args_value_list:
                d = dict(zip(args_name, args_value))  # key+n个value=n个字段
                # d是数据驱动测试的变量，应输入到用例中
                case_info_str = self.to_yaml()  # 转字符串
                case_info_str = Template(case_info_str).render(d)  # 输入变量
                case_info = self.by_yaml(case_info_str)  # 转成类
                case_list.append(case_info)  # 加入到返回值

        return case_list

# if __name__ == '__main__':
#     with open(r"D:\python\TestClass\api_framework\testcases\test_4_blackgood_delete.yaml",
#               encoding="utf-8") as f:
#         data = yaml.safe_load(f)
#     print(data)
#     case_info = CaseInfo(**data)
#
#     s = case_info.to_yaml()  # 字符串
#     # print(s)
#     new_case_info = case_info.by_yaml(s)
#     print(new_case_info)
